package com.shoulder.boot.acl.utils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shoulder.boot.acl.dto.UserQueryDTO;
import com.shoulder.boot.acl.entity.User;
import com.shoulder.boot.acl.vo.UserVo;
import com.shoulder.boot.system.entity.Dept;
import com.shoulder.boot.system.entity.Post;
import com.shoulder.boot.system.entity.Tenant;
import com.shoulder.boot.system.mapper.DeptMapper;
import com.shoulder.boot.system.mapper.PostMapper;
import com.shoulder.boot.system.mapper.TenantMapper;
import com.shoulder.core.enums.StatusEnums;
import com.shoulder.core.utils.FuncUtils;
import com.shoulder.core.utils.MapUtils;
import com.shoulder.mybatis.utils.PageUtils;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Data
public class UserUtils implements PageUtils<User, UserVo> {

    private Map<String, Post> postMap = new HashMap<>();
    private Map<String, Dept> deptMap = new HashMap<>();
    private Map<String, Tenant> tenantMap = new HashMap<>();

    @Override
    public UserVo toVo(User user) {
        UserVo vo = new UserVo();
        BeanUtils.copyProperties(user, vo);
        vo.setDeptName(MapUtils.get(user.getDeptId(), deptMap, new Dept()).getName());
        vo.setPostName(MapUtils.get(user.getPostId(), postMap, new Post()).getName());
        vo.setTenantName(MapUtils.get(user.getTenantId(), tenantMap, new Tenant()).getName());
        vo.setStatusName(StatusEnums.getEnum(user.getStatus()).getDesc());
        return vo;
    }

    public static LambdaQueryWrapper<User> buildQueryWrapper(UserQueryDTO queryDTO) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>().orderByDesc(User::getCreateTime);
        queryWrapper.like(!ObjectUtils.isEmpty(queryDTO.getNickname()), User::getNickname, queryDTO.getNickname());
        queryWrapper.like(!ObjectUtils.isEmpty(queryDTO.getAccount()), User::getAccount, queryDTO.getAccount());
        queryWrapper.like(!ObjectUtils.isEmpty(queryDTO.getPhone()), User::getPhone, queryDTO.getPhone());
        queryWrapper.eq(!ObjectUtils.isEmpty(queryDTO.getStatus()), User::getStatus, queryDTO.getStatus());
        queryWrapper.eq(!ObjectUtils.isEmpty(queryDTO.getTenantId()), User::getTenantId, queryDTO.getTenantId());
        return queryWrapper;
    }

    public static UserUtils buildUtils(List<User> users, DeptMapper deptMapper, PostMapper postMapper, TenantMapper tenantMapper) {
        UserUtils userUtils = new UserUtils();

        List<String> deptIds = FuncUtils.toList(users, User::getDeptId);
        List<String> tenantIds = FuncUtils.toList(users, User::getTenantId);
        List<String> postIds = FuncUtils.toList(users, User::getPostId);

        if (deptMapper != null && !CollectionUtils.isEmpty(deptIds)) {
            userUtils.setDeptMap(deptMapper.selectBatchIds(deptIds)
                    .stream().collect(Collectors.toMap(Dept::getId, Function.identity())));
        }
        if (postMapper != null && !CollectionUtils.isEmpty(postIds)) {
            userUtils.setPostMap(postMapper.selectBatchIds(postIds)
                    .stream().collect(Collectors.toMap(Post::getId, Function.identity())));
        }
        if (tenantMapper != null && !CollectionUtils.isEmpty(tenantIds)) {
            userUtils.setTenantMap(tenantMapper.selectBatchIds(tenantIds)
                    .stream().collect(Collectors.toMap(Tenant::getId, Function.identity())));
        }
        return userUtils;
    }

    public static UserUtils buildUtils() {
        return new UserUtils();
    }
}
